<template>
  <div class="main">
    <div class="main-header">
      <h3>{{ $t("macro.title") }}</h3>
      <div class="big-box">
        <div class="my-box" :key="item.id" v-for="item in numStatistical">
          <el-card shadow="always">
            <span class="tit">
              {{ item.name }}
              <el-popover
                style="background: #fef8ef"
                v-if="item.id == 4"
                placement="bottom"
                :title="yesterday_date"
                width="180"
                trigger="click"
              >
                <div
                  :key="index"
                  v-for="(items, index) in yesterday"
                  style="font-size: 16px; font-weight: 500"
                >
                  <span>{{ items.name }}</span>
                  <span style="display: inline-block; float: right">{{
                    items.yesterday_total
                  }}</span>
                </div>
                <el-button type="text" slot="reference" style="padding: 0">{{
                  $t("macro.yesterday")
                }}</el-button>
              </el-popover>
            </span>
            <div class="light">
              <div class="digits">{{ item.num }}</div>
            </div>
          </el-card>
        </div>
      </div>
    </div>
    <div class="main-content">
      <el-card
        v-loading="host_loading"
        element-loading-text="Loading ..."
        style="margin-top: 35px"
      >
        <div class="title">{{ $t("macro.echarts.host") }}</div>
        <el-result
          icon="success"
          :title="$t('macro.echarts.noHost')"
          :subTitle="$t('macro.echarts.noHostDate')"
          v-show="isHostAbnormal"
        ></el-result>
        <div
          v-show="!isHostAbnormal"
          id="startChart"
          :style="{ width: '100%', minHeight: '220px' }"
        ></div>
      </el-card>
      <el-tabs
        v-model="reptileType"
        @tab-click="selectChange"
        style="margin-bottom: -14px"
      >
        <el-tab-pane label="scrapyd" name="1"></el-tab-pane>
        <el-tab-pane label="python" name="2"></el-tab-pane>
        <el-tab-pane label="other" name="3"></el-tab-pane>
      </el-tabs>
      <el-card v-loading="rep_loading" element-loading-text="Loading ...">
        <div class="title">
          {{ $t("macro.echarts.reptile") + " (total:" + reptileNum + ")" }}
        </div>
        <el-result
          icon="success"
          :title="$t('macro.echarts.noReptile')"
          :subTitle="$t('macro.echarts.noReptileDate')"
          v-show="isReptileAbnormal"
        ></el-result>
        <div
          v-show="!isReptileAbnormal"
          id="startChart"
          :style="{ minWidth: '300px', minHeight: '220px' }"
        ></div>
        <!-- <el-button type="text" icon="el-icon-caret-bottom">显示更多</el-button> -->
      </el-card>
    </div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import chalk from "./chalk";
import "../../../assets/css/font.css";
import $ from "jquery";
export default {
  mounted() {
    // this.startChart();
    this.getAbnormalHost();
    // this.changAabnormalHostData();
    this.getReptileStatistical();
    this.getNumStatistical();
    this.interval = setInterval(() => {
      this.getNumStatistical();
    }, 5000);
  },
  // 销毁组件时，清除定时器
  beforeDestroy() {
    window.clearInterval(this.interval);
  },
  data() {
    return {
      interval: null,
      yesterday: [],
      reptileNum: 0,
      startChart11: null,
      // 异常爬虫类型
      reptileType: "1",
      rep_loading: true,
      host_loading: true,
      // 图表自适应高度
      autoHeight0: "",
      // 数据条数
      counts0: 0,
      // 图表自适应高度
      autoHeight1: "",
      // 数据条数
      counts1: 0,
      // 是否有异常
      isHostAbnormal: false,
      isReptileAbnormal: false,
      abnormal_host_name: [],
      // 假数据
      falseData: {
        code: 0,
        // 异常主机的数据
        abnormal_host: [
          {
            // 主机名
            name: "host1",
            // 主机近期异常状态
            data: [
              { time: "2021/10/18 00:00", state: 0, msg: "" },
              { time: "2021/10/18 04:00", state: 1, msg: "CPU占有率过高" },
              { time: "2021/10/18 08:00", state: 0, msg: "" },
              { time: "2021/10/18 12:00", state: 0, msg: "" },
              { time: "2021/10/18 16:00", state: 1, msg: "磁盘空间不足" },
              { time: "2021/10/18 20:00", state: 0, msg: "" },
              { time: "2021/10/19 00:00", state: 0, msg: "" },
              { time: "2021/10/19 04:00", state: 1, msg: "CPU占有率过高" },
              { time: "2021/10/19 08:00", state: 0, msg: "" },
            ],
          },
        ],
      },
      // 真数据
      abnormalHostData: {},
      // 数量统计
      numStatistical: [
        {
          id: 1,
          name: this.$t("macro.hostNum"),
          enName: "client_count",
          num: "",
        },
        {
          id: 2,
          name: this.$t("macro.projectNum"),
          enName: "project_count",
          num: "",
        },
        {
          id: 3,
          name: this.$t("macro.taskNum"),
          enName: "task_count",
          num: "",
        },
        {
          id: 4,
          name: this.$t("macro.dataTotal"),
          enName: "quantity_total",
          num: "",
        },
      ],
      // Echarts 柱状图数据
      echartsData: [],
      // 爬虫统计数据
      reptileAbnormal: [],
      yesterday_date: "",
    };
  },
  methods: {
    selectChange(val) {
      this.rep_loading = true;
      this.getReptileStatistical();
    },
    // 将得到的主机异常数据转变为可用的数据
    changAabnormalHostData(res) {
      console.log(res);
      let echart = { y: [], data: [] };
      let colors = ["#2EC7C9", "#D6737A"];
      res.abnormal_host.forEach((val, index, arr) => {
        if (val.data.length != 0) {
          // 先获取到主机名展示到异常图里去
          echart.y.push(val.name);
          // 获取异常时间
          val.data.forEach((vals, indexs, arrs) => {
            if (indexs != 0) {
              // console.log(arrs[indexs]);
              // 排除掉第一个数据
              if (vals.state == 0) {
                let normal = {
                  itemStyle: { normal: { color: colors[0] } },
                  name: "normal",
                  value: [index, arrs[indexs - 1].time, arrs[indexs].time],
                };
                echart.data.push(normal);
              } else {
                let abnormal = {
                  itemStyle: { normal: { color: colors[1] } },
                  name: vals.msg,
                  value: [index, arrs[indexs - 1].time, arrs[indexs].time],
                };
                echart.data.push(abnormal);
              }
            }
          });
        }
      });
      console.log(echart);
      return echart;
    },
    // 将得到的爬虫异常数据转变为可用的数据
    changAabnormalHostData1(res) {
      console.log(res);
      let echart = { y: [], data: [] };
      let colors = ["#2EC7C9", "#D6737A"];
      res.abnormal_host.forEach((val, index, arr) => {
        // if (index < 20) {
        if (val.data.length != 0) {
          // 先获取到主机名展示到异常图里去
          echart.y.push(val.name);
          // 获取异常时间
          val.data.forEach((vals, indexs, arrs) => {
            if (vals.state == 0) {
              let normal = {
                itemStyle: { normal: { color: colors[0] } },
                name: "normal",
                value: [index, vals.time + " 00:00", vals.time + " 23:59"],
              };
              echart.data.push(normal);
            } else {
              let abnormal = {
                itemStyle: { normal: { color: colors[1] } },
                name: vals.msg,
                value: [index, vals.time + " 00:00", vals.time + " 23:59"],
              };
              echart.data.push(abnormal);
            }
          });
        }
        // }
      });
      console.log(echart);
      return echart;
    },
    // 获取数量统计数据
    async getNumStatistical() {
      const { data: res } = await this.$http.get("/quantity/statistics");
      let numArr = [];
      // 将后台获取的数据 转换为电子数字形式
      for (let i = 0; i < this.numStatistical.length; i++) {
        this.numStatistical[i].num = res[this.numStatistical[i].enName] + "";
        numArr.push(this.numStatistical[i].num);
      }
      this.yesterday = res.yesterday_data;
      let day = new Date();
      day.setTime(day.getTime() - 24 * 60 * 60 * 1000);
      this.yesterday_date =
        day.getFullYear() + "-" + (day.getMonth() + 1) + "-" + day.getDate();
      // 电子数字函数
      this.clocknum(numArr);
    },
    // 获取主机异常情况
    async getAbnormalHost() {
      const { data: res } = await this.$http.get("/business/abnormal/host");
      console.log("=====主机异常情况=====", res);
      this.abnormalHostData = this.changAabnormalHostData(res);
      // console.log(this.abnormalHostData);
      if (this.abnormalHostData.data.length == 0) {
        this.isHostAbnormal = true;
      }
      this.counts0 = this.abnormalHostData.y.length;
      console.log(this.abnormalHostData);
      this.startChart0();
      this.host_loading = false;
    },
    // 获取爬虫异常数据
    async getReptileStatistical() {
      console.log(123);
      // 获取爬虫统计数据
      const { data: res } = await this.$http.get("/business/abnormal/crawl", {
        params: { type: this.reptileType },
      });
      console.log("=====爬虫异常情况===", res);
      this.reptileNum = res.total;
      // let reptileAbnormal = res
      this.reptileAbnormal = this.changAabnormalHostData1(res);
      console.log("===异常爬虫信息===", this.reptileAbnormal);
      console.log(this.reptileAbnormal.data.length);
      this.counts1 = this.reptileAbnormal.y.length;
      if (this.reptileAbnormal.data.length == 0) {
        this.isReptileAbnormal = true;
      } else {
        this.isReptileAbnormal = false;
      }
      this.startChart1();
      this.rep_loading = false;
    },
    // echarts 渲染
    // 异常主机渲染
    startChart0() {
      let startChart0 = this.$echarts.init(
        document.querySelectorAll("#startChart")[0],
        null,
        { renderer: "svg" }
      );
      this.autoHeight0 = this.counts0 * 35 + 50;
      if (this.counts0 < 6) {
        startChart0.resize({ height: 230 });
      } else {
        startChart0.resize({ height: this.autoHeight0 });
      }

      let colors = ["#2EC7C9", "#D6737A"]; //两种状态的颜色
      let state = this.$t("macro.echarts.state"); //两种状态
      let option0 = {
        color: colors,
        // 提示框
        tooltip: {
          //提示框
          formatter: function (params) {
            return params.name + ":" + params.value[1] + "~" + params.value[2];
          }, //数据的值
        },
        // 图例
        legend: {
          //图例
          data: state,
          bottom: "0%",
          selectedMode: false, // 图例设为不可点击
          textStyle: {
            color: "#000",
          },
        },
        // 位置
        grid: {
          //绘图网格
          left: "3%",
          right: "2%",
          top: "0%",
          bottom: "30px",
          containLabel: true,
        },
        xAxis: {
          // tiggerEvent: true,
          type: "time",
          // interval: 1000 * 3600 * 24 * 2,
          axisLabel: {
            // interval: 1000 * 3600 * 24 * 10,
            formatter: function (value) {
              // console.log(value);
              let date = new Date(value);
              // console.log(date);
              return (
                getzf(date.getHours()) +
                ":" +
                getzf(date.getMinutes()) +
                "\n" +
                date.getDate() +
                "/" +
                (date.getMonth() + 1) +
                " "
              );
              function getzf(num) {
                if (parseInt(num) < 10) {
                  num = "0" + num;
                }
                return num;
              }
            },
          },
        },
        yAxis: {
          // Y轴
          name: "双击可复制",
          // 有异常的主机名
          data: this.abnormalHostData.y,
          // 坐标轴可添加事件
          triggerEvent: true,
        },
        series: [
          // 用空bar来显示四个图例
          { name: state[0], type: "bar", data: [] },
          { name: state[1], type: "bar", data: [] },
          {
            type: "custom",
            renderItem: function (params, api) {
              //开发者自定义的图形元素渲染逻辑，是通过书写 renderItem 函数实现的
              let categoryIndex = api.value(0); //这里使用 api.value(0) 取出当前 dataItem 中第一个维度的数值。
              let start = api.coord([api.value(1), categoryIndex]); // 这里使用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值。
              let end = api.coord([api.value(2), categoryIndex]);

              let height = 10; //柱体宽度

              return {
                type: "rect", // 表示这个图形元素是矩形。还可以是 'circle', 'sector', 'polygon' 等等。
                shape: echarts.graphic.clipRectByRect(
                  {
                    // 矩形的位置和大小。
                    x: start[0],
                    y: start[1] - height / 2,
                    width: end[0] - start[0],
                    height: height,
                  },
                  {
                    // 当前坐标系的包围盒。
                    x: params.coordSys.x,
                    y: params.coordSys.y,
                    width: params.coordSys.width,
                    height: params.coordSys.height,
                  }
                ),
                style: api.style(),
              };
            },
            encode: {
              x: [1, 2], // data 中『维度1』和『维度2』对应到 X 轴
              y: 0, // data 中『维度0』对应到 Y 轴
            },
            data: this.abnormalHostData.data,
          },
        ],
      };
      console.log(startChart0);
      startChart0.setOption(option0); //引用
      // 给坐标轴添加事件
      startChart0.on("click", (params) => {
        console.log(params);
        if (params.componentType == "yAxis") {
          let routeData = this.$router.resolve({
            path: "/Host",
            query: { hostName: params.value },
          });
          window.open(routeData.href, "_blank");
        } else if (params.componentType == "series") {
          // console.log(this.reptileAbnormal.y);
          let hostIndex = params.value[0];
          let hostEnName = this.abnormalHostData.y[hostIndex];
          let routeDataHost = this.$router.resolve({
            path: "/Host",
            query: { hostName: hostEnName },
          });
          window.open(routeDataHost.href, "_blank");
        }
      });

      // 解决echart宽度自适应问题
      window.addEventListener("resize", function () {
        startChart0.resize();
      });
    },
    // 异常爬虫渲染
    startChart1() {
      console.log(this.startChart11);
      if (
        this.startChart11 != null &&
        this.startChart11 != "" &&
        this.startChart11 != undefined
      ) {
        this.startChart11.dispose(); //销毁
      }
      let satrtDom = document.querySelectorAll("#startChart")[1];
      let elCard = document.querySelectorAll(".el-card")[5];
      let widthFun = function () {
        satrtDom.style.width = elCard.offsetWidth - 40 + "px";
      };
      widthFun();
      this.startChart11 = this.$echarts.init(satrtDom);
      // counst.length为柱状图的条数，即数据长度。35为我给每个柱状图的高度，50为柱状图x轴内容的高度(大概的)。
      this.autoHeight1 = this.counts1 * 35 + 50;
      if (this.counts1 < 6) {
        this.startChart11.resize({ height: 230 });
      } else {
        this.startChart11.resize({ height: this.autoHeight1 });
      }
      let colors = ["#2EC7C9", "#D6737A"]; //两种状态的颜色
      let state = this.$t("macro.echarts.state"); //两种状态
      let option1 = {
        color: colors,
        // 提示框
        tooltip: {
          //提示框
          formatter: function (params) {
            return params.name + ":" + params.value[1] + "~" + params.value[2];
          }, //数据的值
        },
        // 图例
        legend: {
          //图例
          data: state,
          bottom: "0%",
          selectedMode: false, // 图例设为不可点击
          textStyle: {
            color: "#000",
          },
        },
        // 位置
        grid: {
          //绘图网格
          left: "0%",
          right: "2%",
          top: "0%",
          bottom: "30px",
          containLabel: true,
        },
        xAxis: {
          type: "time",
          // interval: 1000 * 3600 * 24 * 2,
          axisLabel: {
            // interval: 1000 * 3600 * 24 * 10,
            formatter: function (value) {
              // console.log(value);
              let date = new Date(value);
              // console.log(date);
              return (
                getzf(date.getHours()) +
                ":" +
                getzf(date.getMinutes()) +
                "\n" +
                date.getDate() +
                "/" +
                (date.getMonth() + 1) +
                " "
              );
              function getzf(num) {
                if (parseInt(num) < 10) {
                  num = "0" + num;
                }
                return num;
              }
            },
          },
        },
        yAxis: {
          // Y轴
          // 有异常的主机名
          data: this.reptileAbnormal.y,
          // 坐标轴可添加事件
          triggerEvent: true,
        },
        series: [
          // 用空bar来显示四个图例
          { name: state[0], type: "bar", data: [] },
          { name: state[1], type: "bar", data: [] },
          {
            type: "custom",
            renderItem: function (params, api) {
              //开发者自定义的图形元素渲染逻辑，是通过书写 renderItem 函数实现的
              let categoryIndex = api.value(0); //这里使用 api.value(0) 取出当前 dataItem 中第一个维度的数值。
              let start = api.coord([api.value(1), categoryIndex]); // 这里使用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值。
              let end = api.coord([api.value(2), categoryIndex]);

              let height = 10; //柱体宽度

              return {
                type: "rect", // 表示这个图形元素是矩形。还可以是 'circle', 'sector', 'polygon' 等等。
                shape: echarts.graphic.clipRectByRect(
                  {
                    // 矩形的位置和大小。
                    x: start[0],
                    y: start[1] - height / 2,
                    width: end[0] - start[0] - 10,
                    height: height,
                  },
                  {
                    // 当前坐标系的包围盒。
                    x: params.coordSys.x,
                    y: params.coordSys.y,
                    width: params.coordSys.width,
                    height: params.coordSys.height,
                  }
                ),
                style: api.style(),
              };
            },
            encode: {
              x: [1, 2], // data 中『维度1』和『维度2』对应到 X 轴
              y: 0, // data 中『维度0』对应到 Y 轴
            },
            data: this.reptileAbnormal.data,
          },
        ],
      };
      this.startChart11.setOption(option1); //引用
      this.startChart11.on("click", (params) => {
        console.log(params);
        if (params.componentType == "yAxis") {
          let routeData = this.$router.resolve({
            path: "/Task",
            query: { en_name: params.value },
          });
          window.open(routeData.href, "_blank");
        } else if (params.componentType == "series") {
          // console.log(this.reptileAbnormal.y);
          let repIndex = params.value[0];
          let repEnName = this.reptileAbnormal.y[repIndex];
          let routeDataRep = this.$router.resolve({
            path: "/Reptile",
            query: { en_name: repEnName },
          });
          window.open(routeDataRep.href, "_blank");
        }
      });
      // 解决echart宽度自适应问题
      window.addEventListener("resize", () => {
        widthFun();
        this.startChart11.resize();
      });
    },
    // 利用JQ电子数字显示函数
    clocknum(numArr) {
      $(".digits").empty();
      for (let j = 0; j < numArr.length; j++) {
        let html = "";
        let strarr = numArr[j].toString().split("");
        let digit_to_name =
          "zero one two three four five six seven eight nine".split(" ");
        for (let i = 0; i < strarr.length; i++) {
          if (strarr[i] == ".") {
            html += '<div class="dot"></div>';
          } else {
            let clasname = digit_to_name[strarr[i]];
            html +=
              '<div class="' +
              clasname +
              '">' +
              '<span class="d1"></span>' +
              '<span class="d2"></span>' +
              '<span class="d3"></span>' +
              '<span class="d4"></span>' +
              '<span class="d5"></span>' +
              '<span class="d6"></span>' +
              '<span class="d7"></span>' +
              "</div>";
          }
        }
        $(".digits").eq(j).append(html);
      }
    },
  },
};
</script>

<style lang="less" scoped>
.main {
  // height: 100%;
  // padding: 10px;
  // background-color: aqua;
  .main-header {
    padding: 0 20px 0 20px;
    background-color: #fef8ef;
    // border: 1px solid red;
    h3 {
      margin: 18px 0 10px 0;
    }
    .big-box {
      display: flex;
      .my-box:nth-child(-n + 3) {
        min-width: 240px;
        width: 22%;
      }
      .my-box {
        width: 34%;
        min-width: 385px;
        margin-right: 10px;
      }
    }

    .el-card {
      min-width: 237px;
      background-color: #fef8ef;
      border-left: 4px solid #2ecc71;
      // margin-left: 20px;

      .tit {
        display: block;
        text-align: center;
        margin-bottom: 20px;
        font-weight: 700;
      }
      .light {
        background-color: transparent;
        // margin-left: 40px;
        width: 100%;
        text-align: center;
      }
    }
  }
  .main-content {
    margin-top: 20px;
    // display: flex;
    .el-card {
      // border-left: 4px double #2ecc71;
      // border-top: 4px double #2ecc71;
      // min-height: 230px;
      // height: auto;
      background-color: #fef8ef;
      width: 100%;
      margin: 5px;
      .title {
        color: #606266;
        font-weight: 700;
        font-size: 18px;
        text-align: center;
      }
      .no {
        color: #2ec7c9;
        font-weight: 700;
        font-size: 18px;
        text-align: center;
      }
      .el-button {
        margin: 0 auto;
      }
    }
  }
  #startChart {
    display: block;
    // border: 1px solid red;
    margin-bottom: -20px;
  }
}
</style>